package com.pansoft.openplanet.fragment;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import androidx.core.app.ActivityCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

import com.efounder.constant.EnvironmentVariable;
import com.efounder.frame.baseui.BaseFragment;
import com.efounder.util.FileDeleteUtil;
import com.efounder.util.ToastUtil;
import com.efounder.utils.ResStringUtil;
import com.pansoft.openplanet.R;
import com.pansoft.openplanet.account.model.EthBean;
import com.pansoft.openplanet.account.util.EthAccountGenerator;
import com.pansoft.openplanet.activity.CreateWalletActivity;
import com.pansoft.openplanet.activity.MyWalletActivity;
import com.pansoft.openplanet.activity.SetupAvatarActivity;
import com.pansoft.openplanet.activity.TCBaseActivity;
import com.pansoft.openplanet.activity.TabBottomActivityForTalkChain;
import com.pansoft.openplanet.bean.Account;
import com.pansoft.openplanet.constant.TalkChainConstant;
import com.pansoft.openplanet.db.AccountDao;
import com.pansoft.openplanet.util.LoginFlowManager;
import com.pansoft.openplanet.util.TCAccountManager;
import com.pansoft.openplanet.util.TCRequestUtil;
import com.pansoft.openplanet.widget.TCLoadingDataView;
import com.utilcode.util.ToastUtils;

import org.json.JSONObject;
import org.web3j.crypto.CipherException;
import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.WalletUtils;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.util.HashMap;

import io.reactivex.disposables.Disposable;

import static com.efounder.frame.utils.Constants.CHAT_USER_ID;

/**
 * 使用私钥恢复
 */
public class RestoreByPrivateKeyFragment extends BaseFragment {
    private View rootView;

    private EditText etPrivatekey;
    private Button butEnter;
    private String keyStoreDir;
    private static final String TAG = "RestoreByPrivateKeyFragment";
    private BigInteger privateKey;
    private AccountDao accountDao;
    private String number;
    private String userName;
    private String avatar;


    private String ethPublicKey;
    private String ethAddress;
    private TCAccountManager tcAccountManager;

    private  Account account;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.talk_chain_fragment_retore_byprivatekey, null);
        initView();
        initData();

        return rootView;
    }

    private void initData() {

        number = getActivity().getIntent().getExtras().getString("number");
        userName = getActivity().getIntent().getExtras().getString("userName");
        avatar = getActivity().getIntent().getStringExtra("avatar");

        //创建目录
        keyStoreDir = TalkChainConstant.getDataFilePath(getActivity()) + File.separator + EnvironmentVariable.getUserName();
        File file = new File(keyStoreDir);
        if (!file.exists()) {
            file.mkdirs();
        }
        accountDao = new AccountDao(getActivity());
        tcAccountManager = new TCAccountManager(getActivity());
    }

    private void initView() {
        etPrivatekey = rootView.findViewById(R.id.et_privatekey);
        butEnter = rootView.findViewById(R.id.but_enter);
        butEnter.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //keystore存放的路径
                final String path = TalkChainConstant.getDataFilePath(getActivity()) + File.separator + number;
                //文件夹不存在，创建文件夹
                final File file = new File(path);
                //清空文件夹
                if (file != null) {
                    FileDeleteUtil.delete(file);
                }
                file.mkdirs();
                accountDao.deleteByCurentImuserId();
                restoreByPrivateKey();
            }
        });
    }

    /**
     * 通过私钥恢复账户
     */
    private void restoreByPrivateKey() {
        String key = etPrivatekey.getText().toString().trim();
        if (TextUtils.isEmpty(key)) {
            ToastUtil.showToast(getActivity().getApplicationContext(), ResStringUtil.getString(R.string.open_planet_asset_restoring_key_not_empty));
            return;
        }
        TCLoadingDataView.show(getActivity(), R.string.open_planet_recovering);
        Disposable disposable = EthAccountGenerator.recoverAccountByPrivateKey(keyStoreDir, key, new EthAccountGenerator.GeneratorListener() {
            @Override
            public void generatorSuccess(final EthBean ethBean) {


                if (accountDao.getAccount(ethBean.getEthAddress()) != null) {
                    TCLoadingDataView.dismiss();
                    showCoverAlertDialog();
                    return;
                } else {

                     account = new Account();
                    account.setAccountAvatar(avatar);
                    account.setAddress(ethBean.getEthAddress());
                    account.setFileName(ethBean.getKeyStoreFilePath());
                    account.setAcccountName(userName);
                    account.setImUserId(EnvironmentVariable.getProperty(CHAT_USER_ID));

                    account.setPublicKey(ethBean.getEcKeyPair().getPublicKey().toString());
                    account.setMaster(true);
                    account.setCurrentShow(true);
                    account.setMainAccoutAddress(ethBean.getEthAddress());
                    account.setEnable(false);
                    accountDao.insertOrReplace(account);


                    //判断恢复的钱包地址是否跟服务器一致
                    if (!"".equals(EnvironmentVariable.getProperty("tc_ethAddress", ""))) {
                        if (!account.getAddress().toLowerCase()
                                .equals(EnvironmentVariable.getProperty("tc_ethAddress", "").toLowerCase())) {
                            FileDeleteUtil.delete(new File(ethBean.getKeyStoreFilePath()));
                            accountDao.delete(account.getAddress());
                            TCLoadingDataView.dismiss();
                            showFailAlert(ResStringUtil.getString(R.string
                                    .open_planet_recovering_fail_inconsistency_account));
                            return;
                        }
                    }

                    final String ethPublicKey = ethBean.getEcKeyPair().getPublicKey().toString();
                    final String ethPrivateKey = ethBean.getEcKeyPair().getPrivateKey().toString();
                    final String address = ethBean.getEthAddress();
                    //检查通讯密钥并 上传服务器
//                    tcAccountManager.addChildWallet(ethPublicKey, ethPrivateKey, address, "",
//                            "", IPAssetsConstant.ChainEnum.ETH
//                                    .chainName, new TCAccountManager.AccountManagerListener() {
//                                @Override
//                                public void onSuccess(Object object) {
                    //新建成功后 检查通讯公钥

                    tcAccountManager.checkAndUpdateMessageKey(EnvironmentVariable.getProperty(CHAT_USER_ID),false,
                            new TCAccountManager.AccountManagerListener<String>() {
                                @Override
                                public void onSuccess(String rsaPublicKey) {
                                    TCLoadingDataView.dismiss();
                                    sendToServer(address, ethPublicKey, new File(ethBean.getKeyStoreFilePath()), rsaPublicKey);
                                }

                                @Override
                                public void onFail(String fail) {
                                    TCLoadingDataView.dismiss();
                                    ToastUtil.showToast(getContext(), ResStringUtil.getString(R.string.common_text_http_server_failed));
                                }
                            });

//                                }
//
//                                @Override
//                                public void onFail(String fail) {
//                                    ToastUtil.showToast(getContext(), "服务异常,请重试");
//                                }
//                            });


//                    //todo 2018、0509 生成 RSApublicKey
//                    String[] s = RSAUtil.genKeyPair();
//                    if (s == null) {
//                        ToastUtil.showToast(getActivity(), "生成RSA密钥失败");
//                        return;
//                    }
//                    String rsaPrivateKey = s[0];
//                    String rsaPublicKey = s[1];
//
//                    //保存
//                    EnvironmentVariable.setProperty(RSAUtil.getCurrentPrivateKey(), rsaPrivateKey);
//                    EnvironmentVariable.setProperty(RSAUtil.getCurrentPublicKey(), rsaPublicKey);
//                    ethAddress = ethBean.getEthAddress();
//                    ethPublicKey = ethBean.getEcKeyPair().getPublicKey().toString();
//                    sendToServer(ethAddress, ethPublicKey, new File(ethBean.getKeyStoreFilePath()), rsaPublicKey);

                }
            }

            @Override
            public void generatorFail() {
                TCLoadingDataView.dismiss();
                ToastUtils.showShort(R.string.open_planet_recovering_fail);
            }
        });

        ((TCBaseActivity) getActivity()).addDisposable(disposable);

    }


    //保存结果到服务器
    private void sendToServer(final String address, String publicKey, final File walletFile, String rsaPublicKey) {
        if (address == null || "".equals(address) || publicKey == null || "".equals(publicKey)) {
            showFailAlert(ResStringUtil.getString(R.string.open_planet_recovering_fail_code_300));
            return;
        }
        if (rsaPublicKey == null || "".equals(rsaPublicKey)) {
            showFailAlert(ResStringUtil.getString(R.string.open_planet_recovering_fail_code_301));
            return;
        }

        TCLoadingDataView.show(getActivity(), ResStringUtil.getString(R.string.open_planet_asset_restoring_verifying));
        final HashMap<String, String> map = new HashMap<>();
        map.put("access_token", EnvironmentVariable.getProperty("tc_access_token"));
        map.put("ethAddress", address);
        map.put("ethPublicKey", publicKey);
        map.put("comPublicKey", rsaPublicKey);


        TCRequestUtil.postOAuthRequest(TAG, "user/updateUserEthPublicKeyAndAddress", map,
                new TCRequestUtil.TCRequestCallback() {
                    @Override
                    public void onSuccess(String response) {
                        TCLoadingDataView.dismiss();
                        try {
                            JSONObject jsonObject = new JSONObject(response);

                            if (jsonObject.has("result")
                                    && jsonObject.getString("result")
                                    .equals("success")) {
                                //创建账户成功，本地持久化账户信息
                                //saveAccount();
                                //显示成功对话框
                                //showSuccessAlert();
                                EnvironmentVariable.setProperty("tc_ethAddress", address);
                                ethAddress = address;

                                //结束创建或者恢复钱包的状态
                                EnvironmentVariable.setProperty(LoginFlowManager.getCreateWalletStateKey(number), "false");
                                recoverChildWallet(ethAddress);
                                //goToNextPage();
                            } else {
                                //请求服务器失败，删除本地的keystore文件
                                if (walletFile != null) {
                                    FileDeleteUtil.delete(walletFile);
                                }
                                showFailAlert(ResStringUtil.getString(R.string.open_planet_asset_restoring_fail_server));
                            }
                        } catch (Exception e) {
                            e.printStackTrace();

                            if (walletFile != null) {
                                FileDeleteUtil.delete(walletFile);
                            }
                            showFailAlert(ResStringUtil.getString(R.string.open_planet_asset_restoring_fail_server));
                        }
                    }

                    @Override
                    public void onFail(String error) {
                        TCLoadingDataView.dismiss();
                        if (walletFile != null) {
                            FileDeleteUtil.delete(walletFile);
                        }
                        showFailAlert(ResStringUtil.getString(R.string.open_planet_asset_restoring_fail_net));
                    }
                });

    }

    //恢复子钱包
    private void recoverChildWallet(String mainAddress) {
        TCLoadingDataView.show(getActivity(), ResStringUtil.getString(R.string.open_planet_asset_restoring_child_wallet));
        tcAccountManager.restoreChildWallet(mainAddress, new TCAccountManager.AccountManagerListener<String>() {
            @Override
            public void onSuccess(String object) {
                TCLoadingDataView.dismiss();

                //设置账户可用
                account.setEnable(true);
                accountDao.insertOrReplace(account);

                goToNextPage();
            }

            @Override
            public void onFail(String fail) {
                TCLoadingDataView.dismiss();
                new AlertDialog.Builder(getActivity())
                        .setTitle(R.string.common_text_hint)
                        .setCancelable(false)
                        .setMessage(ResStringUtil.getString(R.string.open_planet_asset_restore_fails))
                        .setPositiveButton(R.string.common_text_confirm, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                recoverChildWallet(ethAddress);
                            }
                        })
                        .create()
                        .show();
            }
        });

    }

    private void goToNextPage() {
        //如果从我的钱包界面过来，跳回原界面
        if (getActivity() != null && getActivity().getIntent().hasExtra(CreateWalletActivity.LAST_ACTIVITY)) {
            String lastActivity = getActivity().getIntent().getStringExtra(CreateWalletActivity.LAST_ACTIVITY);
            if ("myWallet".equals(lastActivity)) {
                Intent intent1 = new Intent(getActivity(), MyWalletActivity.class);
                ActivityCompat.finishAffinity(getActivity());
                return;
            }

        }

        //如果是老用户 并且注册流程 不是没走完的（true 是没走完注册流程）
        if (EnvironmentVariable.getProperty("old_user").equals("1") &&
                !EnvironmentVariable.getProperty(LoginFlowManager.getIsRegisterKey(number), "").equals("true")) {
            Intent intent1 = new Intent(getActivity(), TabBottomActivityForTalkChain.class);
            intent1.putExtra("unDoCheck", "true");//从登录界面跳转无需再次检查是否升级
            //intent1.putExtra("listobj", (Serializable) mainMenus);
            getActivity().startActivity(intent1);
            ActivityCompat.finishAffinity(getActivity());

        } else {
            Intent intent = new Intent(getActivity(), SetupAvatarActivity.class);
            intent.putExtra("id", EnvironmentVariable.getProperty(CHAT_USER_ID));
            intent.putExtra("userName", userName);
            intent.putExtra("number", number);
            startActivity(intent);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        ((TCBaseActivity) getActivity()).dispose();
        if (tcAccountManager.getDisposable() != null) {
            tcAccountManager.getDisposable().dispose();
        }

    }


    private void showFailAlert(String message) {
        if (message == null)
            message = ResStringUtil.getString(R.string.open_planet_recovering_fail_retry);
        new AlertDialog.Builder(getActivity())
                .setTitle(R.string.common_text_hint)
                .setMessage(message)
                .setPositiveButton(R.string.common_text_confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                    }
                })
                .create()
                .show();
    }

    /**
     * 提示是否覆盖的
     */
    private void showCoverAlertDialog() {
        new AlertDialog.Builder(getActivity())
                .setTitle(R.string.common_text_hint)
                .setMessage(ResStringUtil.getString(R.string.open_planet_asset_restore_imported))
                .setPositiveButton(R.string.common_text_confirm, null)
                .create()
                .show();

    }

    /**
     * 导入私钥
     *
     * @param privateKey 私钥
     * @param password   密码
     * @param directory  存储路径
     */
    @SuppressLint("LongLogTag")
    private String importByPrivateKey(BigInteger privateKey, String password, String directory) {
        ECKeyPair ecKeyPair = ECKeyPair.create(privateKey);
        try {
            String keystoreName = WalletUtils.generateWalletFile(password,
                    ecKeyPair,
                    new File(directory),
                    false);
            Log.i(TAG, "importByPrivateKey: " + keystoreName);
            return keystoreName;
        } catch (CipherException | IOException e) {
            e.printStackTrace();
            return null;
        }
    }

}
